package org.zjt.agent.runtime.reloader;

import org.zjt.agent.runtime.classbyte.JavassistClassGenerator;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.logging.Logger;

/**
 * Description:
 *
 * @author juntao.zhang
 * Date: 2018-10-24 4:04 PM
 * @see
 */
public class ClassByteReloader implements ClassReloader {


    private static final Logger LOGGER = Logger.getLogger(ClassByteReloader.class.getName());


    private final Instrumentation inst;

    private final JavassistClassGenerator javassistClassGenerator = new JavassistClassGenerator();

    private List<String> classes = Arrays.asList("AocsValidateTaskSdsdserviceImpl");

    public ClassByteReloader(Instrumentation inst) {
        this.inst = inst;
    }

    @Override
    public Optional<byte[]> redefineClass(String name,byte[] classfileBuffer) {
        name = name.replace("/", ".");
        if (!match(name)){
            return Optional.empty();
        }
        LOGGER.info("classfileBuffer:"+new String(classfileBuffer));
        return javassistClassGenerator.reconstruct(classfileBuffer);
    }

    private boolean match(String name){
        name = name.replace("/", ".");
        LOGGER.info("match class "+name +" match "+ classes.contains(name));
        return classes.contains(name);
    }

    @Override
    public void startup() throws UnmodifiableClassException {
        Class[] allLoadedClasses = inst.getAllLoadedClasses();
        for (Class cl : allLoadedClasses){
            if (classes.contains(cl.getName())){
                inst.retransformClasses(cl);
            }
        }
    }
}
